<div class="parent">
    <label for="hy">There are plenty of events along the lifetime of a drag event. <a href="https://github.com/bevacqua/dragula#drakeon-events">all of them</a> in the docs!</label>
    <div class="wrapper">
        <div class="container" [dragula]="'second-bag'">
            <div>As soon as you start dragging an element, a <code>drag</code> event is fired</div>
            <div>Whenever an element is cloned because <code>copy: true</code>, a <code>cloned</code> event fires</div>
            <div>The <code>shadow</code> event fires whenever the placeholder showing where an element would be dropped is moved to a different container or position</div>
            <div>A <code>drop</code> event is fired whenever an element is dropped anywhere other than its origin <em>(where it was initially dragged from)</em></div>
        </div>
        <div class="container" [dragula]="'second-bag'">
            <div>If the element gets removed from the DOM as a result of dropping outside of any containers, a <code>remove</code> event gets fired</div>
            <div>A <code>cancel</code> event is fired when an element would be dropped onto an invalid target, but retains its original placement instead</div>
            <div>The <code>over</code> event fires when you drag something over a container, and <code>out</code> fires when you drag it away from the container</div>
            <div>Lastly, a <code>dragend</code> event is fired whenever a drag operation ends, regardless of whether it ends in a cancellation, removal, or drop</div>
        </div>
    </div>
    <pre>
      <code>
&lt;div [dragula]=&#039;&quot;second-bag&quot;&#039;&gt;&lt;/div&gt;
&lt;div [dragula]=&#039;&quot;second-bag&quot;&#039;&gt;&lt;/div&gt;

class ExampleB &#123;

  constructor(private dragulaService: DragulaService) &#123;
    dragulaService.drag.subscribe((value) => &#123;
      this.onDrag(value.slice(1));
    });
    dragulaService.drop.subscribe((value) => &#123;
      this.onDrop(value.slice(1));
    });
    dragulaService.over.subscribe((value) => &#123;
      this.onOver(value.slice(1));
    });
    dragulaService.out.subscribe((value) => &#123;
      this.onOut(value.slice(1));
    });
  }

  private hasClass(el: any, name: string) &#123;
    return new RegExp('(?:^|\\s+)' + name + '(?:\\s+|$)').test(el.className);
  }

  private addClass(el: any, name: string) &#123;
    if (!this.hasClass(el, name)) &#123;
      el.className = el.className ? [el.className, name].join(' ') : name;
    }
  }

  private removeClass(el: any, name: string) &#123;
    if (this.hasClass(el, name)) &#123;
      el.className = el.className.replace(new RegExp('(?:^|\\s+)' + name + '(?:\\s+|$)', 'g'), '');
    }
  }

  private onDrag(args) &#123;
    let [e, el] = args;
    this.removeClass(e, 'ex-moved');
  }

  private onDrop(args) &#123;
    let [e, el] = args;
    this.addClass(e, 'ex-moved');
  }

  private onOver(args) &#123;
    let [e, el, container] = args;
    this.addClass(el, 'ex-over');
  }

  private onOut(args) &#123;
    let [e, el, container] = args;
    this.removeClass(el, 'ex-over');
  }
}
      </code>
    </pre>
</div>